﻿using FluentEmail.Core;
using FluentEmail.Core.Models;
using FluentEmail.Smtp;
using furion.blog.Domain.Shared.Dto.Email;
using Furion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using Attachment = FluentEmail.Core.Models.Attachment;

namespace furion.blog.Utils
{
    public class EmailUtil
    {
        private static string SENDER_ACC;
        private static string SENDER_PWD;
        private static string SENDER_EMAIL;
        private static string SMTP_SERVER;
        private static int SMTP_PORT;
        private static string SENDER_SQM;//授权码

        static EmailUtil(){
            EmailUtil.SENDER_ACC = App.Configuration["Email:Sender:Account"];
            EmailUtil.SENDER_PWD = App.Configuration["Email:Sender:Password"];
            EmailUtil.SENDER_EMAIL = App.Configuration["Email:Sender:Email"];
            EmailUtil.SENDER_SQM = App.Configuration["Email:Sender:Sqm"];
            EmailUtil.SMTP_SERVER = App.Configuration["Email:SmtpServer"];
            EmailUtil.SMTP_PORT = int.Parse(App.Configuration["Email:SmtpPort"]);
        }

        public EmailUtil()
        {

        }

        public static async Task<bool> Send(string toUsers, string subject, string content)
        {
            return await Send(toUsers, subject, content, null, null, null, null);
        }

        public static async Task<bool> Send(string toUsers, string subject, string content, Action<EmailSendDto> succAction)
        {
            return await Send(toUsers, subject, content, null, succAction, null, null);
        }

        public static async Task<bool> Send(string toUsers, string subject, string content, Action<EmailSendDto> succAction, Action<EmailSendDto, string> failAction)
        {
            return await Send(toUsers, subject, content, null, succAction, failAction, null);
        }

        public static async Task<bool> Send(string toUsers, string subject, string content, List<Attachment> attachList)
        {
            return await Send(toUsers, subject, content, attachList, null, null, null);
        }

        public static async Task<bool> Send(string toUsers, string subject, string content, List<Attachment> attachList, Action<EmailSendDto> succAction)
        {
            return await Send(toUsers, subject, content, attachList, succAction, null, null);
        }

        public static async Task<bool> Send(string toUsers, string subject, string content, List<Attachment> attachList, Action<EmailSendDto> succAction, Action<EmailSendDto, string> failAction)
        {
            return await Send(toUsers, subject, content, attachList, succAction, failAction, null);
        }

        /// <summary>
        /// 设置smtp信息
        /// </summary>
        private static void SetDefaultSetting()
        {
            //使用smtp服务发送邮件必须要设置smtp服务信息
            var smtp = new SmtpClient
            {
                Host = EmailUtil.SMTP_SERVER,//smtp服务器地址
                Port = (int)EmailUtil.SMTP_PORT,//端口号，默认为25
                EnableSsl = false,
                UseDefaultCredentials = false,
                //DeliveryMethod = SmtpDeliveryMethod.Network,
                Credentials = new NetworkCredential(EmailUtil.SENDER_ACC, EmailUtil.SENDER_SQM)
            };

            //设置默认发送信息
            Email.DefaultSender = new SmtpSender(smtp);
        }

        /// <summary>
        /// 发送邮件（异步）
        /// </summary>
        /// <param name="toUsers">接收人（多个人用英文的分号分隔），格式如：qubernet@163.com或qubernet@163.com;757200834@qq.com</param>
        /// <param name="subject">主题</param>
        /// <param name="content">内容（支持Html）</param>
        /// <param name="attachList">附件集合，具体格式如下</param>
        /// <param name="succAction">发送成功回调（返回主题和内容参数）</param>
        /// <param name="failAction">发送失败回调（返回主题、内容和失败原因参数）</param>
        /// <param name="ccUsers">抄送人，格式和接收人参数一致</param>
        /// <returns></returns>
        public static async Task<bool> Send(
            string toUsers,
            string subject,
            string content,
            List<Attachment> attachList,
            Action<EmailSendDto> succAction,
            Action<EmailSendDto, string> failAction,
            string ccUsers)
        {
            /*
             * 
             *  attachList参数示例：
                new List<FluentEmail.Core.Models.Attachment>
                {
                    new FluentEmail.Core.Models.Attachment{
                        Data = System.IO.File.OpenRead("Quber.Core.Service项目库说明.txt"),
                        ContentType = "text/plain",
                        Filename = "Quber.Core.Service项目库说明.txt"
                    },
                    new FluentEmail.Core.Models.Attachment{
                        Data = System.IO.File.OpenRead("003.jpg"),
                        ContentType = "image/*",
                        Filename = "003.jpg"
                    }
                })
             * 
             */

            SetDefaultSetting();

            var ret = true;

            try
            {
                List<Address> toUserList = null, ccUserList = null;
                if (toUsers != null) toUserList = toUsers.Split(';').Select(m => new Address { EmailAddress = m }).ToList();
                if (ccUserList != null) ccUserList = ccUsers.Split(';').Select(m => new Address { EmailAddress = m }).ToList();

                var email = Email
                    .From(EmailUtil.SENDER_EMAIL)    //发送人
                    .Subject(subject)           //邮件标题
                    .Body(content, true);       //邮件内容

                if (toUserList != null) email = email.To(toUserList);    //收件人
                if (ccUserList != null) email = email.CC(ccUserList);    //抄送人
                if (attachList != null) email = email.Attach(attachList);//添加附件

                var result = await email.SendAsync();

                if (result.Successful)
                {
                    if (succAction != null) succAction(new EmailSendDto { 
                      Title = subject,
                      Content = content,
                      From = EmailUtil.SENDER_EMAIL,
                      To = toUsers??string.Empty,
                      Cc = ccUsers??String.Empty,
                    });
                }
                else
                {
                    if (failAction != null)
                    {
                        //发送失败的原因
                        var sendFailMsg = result.ErrorMessages;
                        failAction(
                            new EmailSendDto
                            {
                                Title = subject,
                                Content = content,
                                From = EmailUtil.SENDER_EMAIL,
                                To = toUsers??string.Empty,
                                Cc = ccUsers??String.Empty,
                            }
                            , string.Join('；', sendFailMsg));
                    }

                    ret = false;
                }

            }
            catch (Exception ex)
            {
                if (failAction != null) failAction(
                    new EmailSendDto
                    {
                        Title = subject,
                        Content = content,
                        From = EmailUtil.SENDER_EMAIL,
                        To = toUsers ?? string.Empty,
                        Cc = ccUsers ?? String.Empty,
                    }, ex.Message);

                ret = false;
            }

            return ret;
        }
    }

}
